home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / lzsfx.com / LZSTUB.ASM < prev    next >
Encoding:
Assembly Source File  |  1989-06-02  |  13.7 KB  |  514 lines

  1.  
  2. ; LZSTUB.ASM -- LZSS self-extract pgm
  3. ; June 2, 1989
  4. ;
  5. ; $Log: RCS/LZSTUB.ASM $
  6. ;
  7. ; revision 1.5 MAS 89/06/02 03:47:58
  8. ; ask overwrite.
  9. ; exec autolarc.bat
  10. ; check crc.
  11. ;
  12. ; revision 1.4 MAS 89/01/31 04:24:52
  13. ; for LArc 3.XX (-lz4-, -lz5-)
  14. ; check disk-full.
  15. ;
  16. ; revision 1.3 MAS 88/07/10 20:44:12
  17. ; getbit made quick.
  18. ; all segment bugs fixed.
  19. ;
  20. ; revision 1.2 MAS 88/06/18 22:05:59
  21. ; generate .exe file.
  22. ; some bugs (esp. segment check) fixed.
  23. ; smaller output buffer.
  24. ;
  25. ; revision 1.1 MAS 88/05/22 17:44:54
  26. ; Initial revision
  27. ;
  28. ;
  29. include lms.inc                 ;; V2.3 by SO                                                                   ;; cf. break1, break2
  30. ;
  31. MINLEN  =       3               ; THRESHOLD + 1.
  32. N       =       4096            ; buffer size  2^12.
  33. F       =       15+MINLEN       ; lookahead buffer size.
  34. ;
  35. crc16   =       0a001h
  36. BUFHEAD =       N               ; output buffer head addr.
  37. BUFSIZ  =       2000h           ; output buffer size (maximum)
  38. CRCHEAD =       BUFHEAD+BUFSIZ
  39. CRCSIZ  =       512             ; 256*2
  40. WRKHEAD =       CRCHEAD+CRCSIZ
  41. ;
  42. lzhead  struc
  43. headsiz db      ?
  44. headchk db      ?
  45. headid  db      5 dup (?)       ; '-lz4-' '-lz5-'
  46. ssize   dd      ?
  47. dsize   dd      ?
  48. time    dw      ?
  49. date    dw      ?
  50. attr    dw      ?
  51. fnlen   db      ?
  52. lzhead  ends
  53. ;
  54. work    struc
  55. count           dd      ?               ; size of source.
  56. fhandl          dw      ?
  57. bufptr          dw      ?
  58. curcrc          dw      ?
  59. orgcrc          dw      ?
  60. work    ends
  61. ;
  62. autol   struc
  63.         db      8, "AUTOLARC"
  64. ;
  65. autosw  db      ".BAT"
  66. ;
  67. autol   ends
  68. ;
  69. pushs   macro   regs
  70.         irp     areg, <regs>
  71.         push    areg
  72.         endm
  73.         endm
  74. ;
  75. pops    macro   regs
  76.         irp     areg, <regs>
  77.         pop     areg
  78.         endm
  79.         endm
  80. ;
  81. movsr   macro   dst, src
  82.         push    src
  83.         pop     dst
  84.         endm
  85. ;
  86. msdos   macro   num
  87.         ifnb    <num>
  88.         if      num ge 100h
  89.         mov     ax, num
  90.         else
  91.         mov     ah, num
  92.         endif
  93.         endif
  94.         int     21h
  95.         endm
  96. ;
  97. code    segment byte public
  98.         assume cs:code
  99. ;
  100. zero    label   byte
  101. ;
  102. ; -------- print messages -------------
  103. ;
  104. open_msg        db      "LZSS self extract"     ; must org 0.
  105. crlf_msg        db      0dh, 0ah, "$"
  106. wrt_err_msg     db      "write error$"
  107. open_err_msg    db      "can't open$"
  108. already_msg     db      "exists. Overwrite[y/n]$"
  109. crc_err_msg     db      7, "fails crc$"
  110. ;
  111. ; -------- autolarc -------------------
  112. ;
  113. autolarc        autol   <>
  114. ;
  115. checkcrc:
  116.         mov     ax, [bp].orgcrc
  117.         cmp     [bp].curcrc, ax
  118.         mov     dx, offset crc_err_msg
  119.         jnz     print
  120.         ret
  121. ;
  122. crlf:   mov     dx, offset crlf_msg
  123. ;
  124. print:
  125.          ifdef  LARGE
  126.         push    ds
  127.         movsr   ds, cs
  128.         msdos   9
  129.         pop     ds
  130. ;
  131.          else
  132.         msdos   9
  133.          endif
  134. ;
  135.         ret
  136. ;
  137. putc:   push    dx
  138.         xchg    ax, dx
  139.         msdos   2
  140.         pop     dx
  141.         ret
  142. ;
  143. eject_err:
  144.         mov     dx, offset wrt_err_msg
  145. print_err:
  146.         call    print
  147.         call    crlf
  148.         msdos   4c01h           ; error exit
  149. ;
  150. ;----------------------------------------
  151. ;       output to file
  152. ;----------------------------------------
  153. ;
  154. ; fputc --
  155. ; in al = char. destroy nothing.
  156. ;
  157. fputc   proc
  158.         push    di
  159.         mov     di, [bp].bufptr
  160. ;
  161.         .if     <di ae BUFSIZ+BUFHEAD>
  162.                 call    eject
  163.                 mov     di, BUFHEAD
  164.         .endif
  165. ;
  166.         stosb
  167.         mov     [bp].bufptr, di
  168.         pop     di
  169.         ret
  170. ;
  171. fputc   endp
  172. ;
  173. ; Eject - destroy nothing.
  174. ;
  175. eject   proc
  176.         pushs   <ds,si,dx,cx,bx,ax>
  177.         .do
  178.                 movsr   ds, es
  179.                 mov     si, BUFHEAD
  180.                 mov     cx, [bp].bufptr
  181.                 sub     cx, si
  182.                 jz      break1
  183.                 pushs   <si, cx>                ; si = buffer
  184.                 mov     dx, [bp].curcrc         ; dx = crc
  185.                 .do
  186.                         lodsb
  187.                         xor     al, dl                  ; crc and $FF xor c
  188.                         mov     ah, 0
  189.                         shl     ax, 1
  190.                         xchg    bx, ax
  191.                         mov     dl, dh                  ; crc shr 8
  192.                         mov     dh, 0
  193.                         xor     dx, es:[bx]+CRCHEAD     ; xor crctable
  194.                 .loop
  195.                 mov     [bp].curcrc, dx
  196.                 pops    <cx, dx>
  197.  
  198.                 mov     bx, [bp].fhandl
  199.                 msdos   40h             ; write to file
  200.                 jc      eject_err       ; error or
  201.                 cmp     ax, cx          ; disk full
  202.                 jnz     eject_err
  203.                 mov     al, '.'
  204.                 call    putc
  205.         .until
  206. ;
  207. break1: pops    <ax,bx,cx,dx,si,ds>
  208.  
  209. eject_exit:
  210.         ret
  211. ;
  212. eject   endp
  213. ;
  214. ;---------------------------------------;
  215. ;   decoder.                            ;
  216. ;       in ds:si = lzs data start -1    ;
  217. ;       out ds:si                       ;
  218. ;       destroy all                     ;
  219. ;---------------------------------------;
  220. ;
  221. decode  proc
  222.         xor     di, di
  223.         mov     al, 0
  224.         .do
  225.                 mov     cx, 0dh
  226.                 rep     stosb
  227.                 inc     al
  228.         .until  <z>
  229.         .do
  230.                 stosb
  231.                 inc     al
  232.         .until  <z>
  233.         .do
  234.                 dec     al
  235.                 stosb
  236.         .until  <z>
  237.         mov     cx, 80h
  238.         push    cx
  239.         rep     stosb
  240.         pop     cx
  241.         mov     al, ' '
  242.         rep     stosb
  243.         mov     di, N-F
  244.         mov     dl, 80h         ; mask 1,2,4,8,..80h
  245.         .while
  246.                 rol     dl, 1
  247. ;
  248.                 .if     <c>
  249.                         call    getc
  250.                         jc      eject_exit
  251.                         mov     dh, al          ; flags.
  252.                 .endif
  253. ;
  254.                 call    getc
  255.                 jc      eject_exit
  256.                 test    dh, dl          ; if flag on then 1 char.
  257. ;
  258.                 .if     <nz>
  259.                         call    fputc   ; fputc(c)
  260.                         stosb           ; buf[di] := c; di := (di+1) mod N
  261.                         and     di, N-1
  262.                         .continue
  263.                 .endif
  264. ;
  265.                 xchg    bx, ax          ;  (bl=al)
  266.                 call    getc            ; else  cx := len, bx := po;
  267.                 jc      eject_exit
  268.                 mov     bh, al          ;  ( pos = lo + hi&f0h >>4 )
  269.                 mov     cl, 4
  270.                 shr     bh, cl
  271.                 and     ax, 0fh         ;  ( len = (hi & 0fh) + MINLEN )
  272.                 add     al, MINLEN
  273.                 xchg    cx, ax
  274.                 .do
  275.                         mov     al, es:[bx]
  276.                         call    fputc
  277.                         inc     bx
  278.                         and     bh, (N-1) shr 8
  279.                         stosb
  280.                         and     di, N-1
  281.                 .loop
  282.         .enddo
  283. ;
  284. decode  endp
  285. ;
  286. ; Getc
  287. ;       in-out ds:si = pos.  out al = c, CF = eof.
  288. ;       destroy  ah
  289. ;
  290. getc    proc
  291.         ifdef   LARGE
  292.         sub     word ptr [bp].count, 1
  293.         sbb     word ptr [bp].count+2, 0
  294.         .if     <nc>
  295.                 inc     si
  296.                 .if     <z>
  297.                         mov     ax, ds
  298.                         add     ax, 1000h ; 0:ffff(0ffff)+1 = 1000:0 (10000)
  299.                         mov     ds, ax
  300.                 .endif
  301.         else
  302.         sub     word ptr [bp].count, 1
  303.         .if     <nc>
  304.                 inc     si
  305.         endif
  306.                 mov     al, [si]
  307.                 clc
  308.         .endif
  309.         ret
  310. getc    endp
  311. ;
  312. ;-------------------------------;
  313. ;       main program.           ;
  314. ;-------------------------------;
  315. ;
  316. begin:  cld
  317.         push    ds                      ; use to exec autolarc.
  318.         movsr   es, ss                  ; es(work/output buffer) = ss.
  319.         movsr   ds, cs                  ; initial value of ds = cs.
  320.         mov     bp, WRKHEAD             ; bp = work area ptr.
  321.         xor     dx, dx                  ; open msg
  322.         call    print
  323.         mov     di, CRCHEAD
  324.         xor     dx, dx
  325.         .do
  326.                 mov     ax, dx
  327.                 mov     cx, 8
  328.                 .do
  329.                         shr     ax, 1
  330.                         .if     <c>
  331.                                 xor     ax, crc16
  332.                         .endif
  333.                 .loop
  334.                 stosw
  335.                 inc     dl
  336.         .until  <z>
  337.         mov     si, offset memend
  338. ;
  339. main_loop:
  340.         .if     <[si].headsiz e 0>
  341.                 pop     es                      ; PSP segment.
  342.                 mov     bx, ((main_next-zero)+15)/16 + 10h      ; 10h for PSP.
  343.                 msdos   4ah                                     ; resize memory block.
  344.         ifdef   LARGE
  345.                 movsr   ds, cs
  346.         endif
  347.                 mov     si, offset autolarc
  348.                 .if     <[si].autosw ne '.'>    ; autolarc exist?
  349.                         int     2eh                                     ; execute command.
  350.                 .endif
  351.                 msdos   4c00h                           ; terminate program.
  352.         .endif
  353. ;
  354. main_next       label   near
  355.         pushs   <es, si>
  356.         lea     si, [si].fnlen          ; change name to asciz
  357.         mov     di, si
  358.         mov     dx, si                  ; for open function call
  359.         lodsb
  360.         mov     ah, 0
  361.         xchg    cx, ax
  362.         movsr   es, ds
  363.         rep     movsb
  364.         mov     ax, [di+1]              ; get crc
  365.         mov     [bp].orgcrc, ax
  366.         mov     byte ptr [di], '$'      ; print file name
  367.         msdos   9
  368.         mov     al, ' '
  369.         call    putc
  370.         mov     byte ptr [di], 0        ; to asciz
  371.         mov     di, offset autolarc+1   ; check autolarc
  372.         ifdef   LARGE
  373.         movsr   es, cs
  374.         endif
  375.         mov     si, dx
  376.         mov     cx, (type autol)-1
  377.         repe    cmpsb
  378.         pops    <si, es>
  379.         push    dx
  380.         .do
  381.                 .if     <z>
  382. ;
  383.         ifdef LARGE
  384.                         mov     byte ptr cs:[di]-4, 0dh
  385.         else
  386.                         mov     byte ptr [di]-4, 0dh
  387.         endif
  388. ;
  389.                 .else
  390.                         msdos   3d00h                   ; open for input
  391.                         jc      break2
  392.                         xchg    bx, ax                  ; bx=file handle
  393.                         msdos   3eh                     ; close
  394.                         mov     dx, offset already_msg
  395.                         call    print
  396.                         .do
  397.                                 mov     dl, 0ffh
  398.                                 msdos   6
  399.                                 and     al, 0dfh                ; upcase
  400.                                 cmp     al, 'Y'
  401.                                 jz      break2
  402.                         .until  <al e 'N'>
  403.                         call    putc
  404.                         pop     dx
  405.                         jmp     short   main_skip
  406.                 .endif
  407.         .until
  408. ;
  409. break2: pop     dx
  410.  
  411.         xor     cx, cx
  412.         msdos   3ch                     ; create
  413.         .if     <c>
  414.                 mov     dx, offset open_err_msg
  415.                 jmp     print_err
  416.         .endif
  417.         mov     [bp].fhandl, ax         ; init output
  418.         mov     [bp].bufptr, BUFHEAD
  419.         mov     [bp].curcrc, 0
  420.         mov     ax, word ptr [si].ssize ; init input
  421.         mov     word ptr [bp].count, ax
  422. ;w
  423.         ifdef   LARGE
  424.         mov     ax, word ptr [si].ssize+2
  425.         mov     word ptr [bp].count+2, ax
  426.         push    ds
  427.         endif
  428. ;
  429.         push    si
  430.         mov     bl, [si].headid+3       ; '4' or '5'
  431.         call    srchead
  432.         add     si, ax
  433.         dec     si
  434.         shr     bl, 1
  435.         .if     <nc>
  436.                 .while
  437.                         call    getc    ; Storing
  438.                         jc      decode45
  439.                         call    fputc
  440.                 .enddo
  441.         .endif
  442.         call    decode                  ; Main
  443. ;
  444. decode45:
  445.         call    eject
  446.         pop     si
  447. ;
  448.         ifdef   LARGE
  449.         pop     ds
  450.         endif
  451. ;
  452.         mov     bx, [bp].fhandl
  453.         mov     cx, [si].time           ; set date/time
  454.         mov     dx, [si].date
  455.         msdos   5701h
  456.         msdos   3eh                     ; close file.
  457.         mov     cx, [si].attr           ; change file attr.
  458.         lea     dx, [si].fnlen
  459.         msdos   4301h
  460.         call    checkcrc
  461. ;
  462. main_skip:
  463.         call    crlf
  464. ;
  465. ; ds:si += (ssize + headsiz + 2)
  466. ;
  467.         call    srchead
  468. ;
  469.         ifdef   LARGE
  470.         mov     bx, word ptr [si].ssize+2
  471.         mov     cl, 12
  472.         shl     bx, cl
  473.         add     ax, word ptr [si].ssize
  474.         mov     dx, ds
  475.         adc     dx, bx
  476.         add     si, ax
  477.         .if     <c>
  478.                 add     dh, 10h
  479.         .endif
  480. ;
  481.         mov     ax, si          ; Normalize pointer
  482.         mov     cl, 4
  483.         shr     ax, cl
  484.         add     dx, ax          ; ds = ds + (si div 16)
  485.         and     si, 15          ; si = si mod 16
  486.         mov     ds, dx
  487. ;
  488.         else
  489.         add     ax, word ptr [si].ssize
  490.         add     si, ax
  491.         endif
  492. ;
  493.         jmp     main_loop
  494. ;
  495. srchead proc
  496.         mov     al, [si].headsiz
  497.         mov     ah, 0
  498.         inc     ax
  499.         inc     ax
  500.         ret
  501. srchead endp
  502. ;
  503. memend  label   byte
  504. ;
  505. code    ends
  506. ;
  507. stack   segment word stack
  508. ;
  509.         db      WRKHEAD+200     dup     (?)
  510. ;
  511. stack   ends
  512. ;
  513.         end     begin
  514.